/////////////////////////////////////////////////////////////////////
// DBMysql.cpp
//
//
// 11/16/2010
//
/////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DBMysql.h"

inline int ___atoi(const char* szNumber)
{
	if (szNumber)
		return atoi(szNumber);
	else
		return 0;
}

inline __int64 ___atoi64(const char* szNumber)
{
	if (szNumber)
		return _atoi64(szNumber);
	else
		return 0;
}



DBMysql::DBMysql( void )
: m_mysql( 0 ),
  m_curResult( 0 ),
  m_curRow( 0 ),
  m_nCurRows( 0 )
{
}

bool DBMysql::Create( std::string ip, std::string username, std::string pwd, std::string db, short nPort )
{
	m_ip = ip;
	m_username = username;
	m_pwd = pwd;
	m_db = db;
	m_nPort = nPort;

	if ( !m_mysql )
	{
		m_mysql = mysql_init( NULL );
	}

	return Create();
}

bool DBMysql::Create( void )
{
	if ( !m_mysql )
	{
		return false;
	}

	if ( m_mysql != mysql_real_connect( m_mysql, m_ip.c_str(), m_username.c_str(), m_pwd.c_str(), m_db.c_str(), m_nPort, NULL, CLIENT_MULTI_STATEMENTS ) )
	{
		printf( "Failed to connect the database!\n" );
		return false;
	}

	if ( mysql_set_character_set( m_mysql, "gbk" ) != 0 )
	{
		printf( "Failed to set character!\n" );
		return false;
	}

	return true;
}

void DBMysql::Destroy( void )
{
	mysql_close( m_mysql );
}

int DBMysql::EscapeString( char * to, const char * from )
{
	if ( m_mysql )
		return (int)mysql_real_escape_string( m_mysql, to, from ,(unsigned long)strlen( from ) );
	else
		return 0;
}

int DBMysql::EscapeString( char * to , const void * from )
{
	if ( m_mysql )
		return (int)mysql_real_escape_string( m_mysql, to, (const char *)from, (unsigned long)strlen( (const char *)from ) );
	else
		return 0;
}

INT64 DBMysql::Query( const char * sql )
{
	if ( !m_mysql )
	{
		if ( Create( m_ip.c_str(), m_username.c_str(), m_pwd.c_str(), m_db.c_str(), m_nPort ) )
		{
			printf( "Success to connect the database!\n" );
		}
		else
		{
			printf( "Failed to connect the database!\n" );
			return -1;
		}
	}

	if ( 0 != mysql_real_query( m_mysql, sql, (unsigned long)strlen( sql ) ) )
	{
		int nErr = mysql_errno( m_mysql );
		printf( "Failed to query database errno : %d\n", nErr );
		printf( "Error string : %s\n", mysql_error( m_mysql ) );
		//CR_SERVER_GONE_ERROR CR_SERVER_LOST
		if ( nErr == 2006 || nErr == 2013 )
		{
			if ( Create() )
			{
				printf( "Success to connect the database!\n" );
				if ( !mysql_real_query( m_mysql, sql, (unsigned long)strlen( sql ) ) )
				{
					printf( "Failed to query database again!\n" );
					printf( "Errno : %d Error : %s\n", mysql_errno( m_mysql ), mysql_error( m_mysql ) );
					return -1;
				}
			}
			else
			{
				printf( "Failed to connect database!\n" );
				return -1;
			}
		}
		else
		{
			return -1;
		}
	}

	mysql_free_result( m_curResult );
	m_curResult = mysql_store_result( m_mysql );

	m_nCurRows = mysql_affected_rows( m_mysql );
	m_curRow = NULL;

	//temporary fix.
	//fix the error 2014 when execute sql.
	//vincent
	do 
	{
		mysql_store_result( m_mysql );
	} while (!mysql_next_result(m_mysql));

	return m_nCurRows;
}

void DBMysql::FreeResult( void )
{
	mysql_free_result( m_curResult );
}

bool DBMysql::GetRow( void )
{
	m_curRow = mysql_fetch_row( m_curResult );
	return ( ( m_curRow != NULL ) && ( *m_curRow != NULL ) );
}

void DBMysql::GetField( UINT64 &data, int idx )
{
	if ( m_curRow )
		data = (UINT64)( ___atoi64( m_curRow[idx] ) & 0xffffffffffffffff );
	else
		data = 0;
}

void DBMysql::GetField( INT64 &data, int idx )
{
	if ( m_curRow )
		data = (INT64)( ___atoi64( m_curRow[idx] ) & 0xffffffffffffffff );
	else
		data = 0;
}

void DBMysql::GetField( UINT32 &data, int idx )
{
	if ( m_curRow )
		data = (UINT32)( ___atoi( m_curRow[idx] ) & 0xffffffff );
	else
		data = 0;
}

void DBMysql::GetField( INT32 &data, int idx )
{
	if ( m_curRow )
		data = (INT32)( ___atoi( m_curRow[idx] ) & 0xffffffff );
	else
		data = 0;
}

void DBMysql::GetField( UINT16 &data, int idx )
{
	if ( m_curRow )
		data = (UINT16)( ___atoi( m_curRow[idx] ) & 0xffff );
	else
		data = 0;
}

void DBMysql::GetField( INT16 &data, int idx )
{
	if ( m_curRow )
		data = (INT16)( ___atoi( m_curRow[idx] ) & 0xffff );
	else
		data = 0;
}

void DBMysql::GetField( UINT8 &data, int idx )
{
	if ( m_curRow )
		data = (UINT8)( ___atoi( m_curRow[idx] ) & 0xff );
	else
		data = 0;
}

void DBMysql::GetField( INT8 &data, int idx )
{
	if ( m_curRow )
		data = (INT8)( ___atoi( m_curRow[idx] ) & 0xff );
	else
		data = 0;
}

void DBMysql::GetField( bool &data, int idx )
{
	if ( m_curRow )
		data = 0!=(___atoi( m_curRow[idx] ) & 0xff );
	else
		data = false;
}

void DBMysql::GetField( char &data, int idx )
{
	if ( m_curRow )
		data = (char)( ___atoi( m_curRow[idx] ) & 0xff );
	else
		data = 0;
}

void DBMysql::GetField( void * buffer, unsigned long len, int idx )
{
	if ( m_curRow )
		memcpy( buffer, m_curRow[idx], len );
}

void DBMysql::GetField( char * szString, unsigned long len, int idx )
{
	if ( m_curRow )
		memcpy( szString, m_curRow[idx], len );
}

void DBMysql::GetField( string& str, int idx )
{
	if ( m_curRow )
		str = m_curRow[idx];
}